package com.cgmnx.admin.common.bean;


import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;

@Setter
@Getter
@ToString
public class ApiRes<T> implements Serializable {

    private boolean ret;

    @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
    private String msg;

    private int errcode;

    @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
    private T data;

    public ApiRes() {
        this.ret = true;
        this.data = null;
        this.errcode = 0;
    }

    public ApiRes(T t) {
        this.ret = true;
        this.data = t;
    }

    private ApiRes(String errmsg, T t) {
        this.ret = false;
        this.msg = errmsg;
        this.data = t;
    }

    private ApiRes(int errcode, String errmsg, T t) {
        this.ret = false;
        this.msg = errmsg;
        this.data = t;
        this.errcode = errcode;
    }

    public static <T> ApiRes<T> returnSuccess() {
        return new ApiRes<T>(null);
    }

    public static <T> ApiRes<T> returnSuccess(T t) {
        return new ApiRes<T>(t);
    }

    public static <T> ApiRes<T> returnFail(String errmsg) {
        return new ApiRes<T>(errmsg, null);
    }

    public static <T> ApiRes<T> returnFail(String errmsg, T t) {
        return new ApiRes<T>(errmsg, t);
    }

    public static <T> ApiRes<T> returnFail(int errcode, String errmsg) {
        return new ApiRes<T>(errcode, errmsg, null);
    }

    public static <T> ApiRes<T> returnFail(int errcode, String errmsg, T t) {
        return new ApiRes<T>(errcode, errmsg, t);
    }

    public static <T> ApiRes list(Collection<T> content, Integer totalRows) {
        Preconditions.checkNotNull(content);  // fast fail
        ApiRes result = new ApiRes();
        Map<String, Object> map = Maps.newHashMap();
        map.put("list", content);
        if (totalRows == null) {
            map.put("totalRows", content.size());
        } else {
            map.put("totalRows", totalRows);
        }
        result.data = map;
        return result;
    }


    public static <T> ApiRes list(Collection<T> content) {
        return list(content, null);
    }


    public static <T> ApiRes emptyList() {
        return list(Collections.emptySet());
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((data == null) ? 0 : data.hashCode());
        result = prime * result + ((msg == null) ? 0 : msg.hashCode());
        result = prime * result + (ret ? 1231 : 1237);
        result = prime * result + errcode;
        return result;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        ApiRes that = (ApiRes) o;

        if (errcode != that.errcode)
            return false;
        if (ret != that.ret)
            return false;
        if (data != null ? !data.equals(that.data) : that.data != null)
            return false;
        if (msg != null ? !msg.equals(that.msg) : that.msg != null)
            return false;

        return true;
    }

}
